package org.bronycorps.mlptss.manager.ai;

import org.bronycorps.mlptss.domain.actor.AbstractActor;
import org.bronycorps.mlptss.domain.actor.EnemyActor;
import org.bronycorps.mlptss.domain.actor.MissileActor;
import org.bronycorps.mlptss.domain.actor.SpecialMissileActor;
import org.bronycorps.mlptss.domain.ai.PredictedStage;
import org.bronycorps.mlptss.domain.ai.actor.VirtualActor;
import org.bronycorps.mlptss.domain.ai.actor.VirtualDestructibleActor;
import org.bronycorps.mlptss.domain.ai.actor.VirtualIndestructibleActor;
import org.bronycorps.mlptss.domain.ai.tweenable.VirtualDestructibleAccessor;
import org.bronycorps.mlptss.domain.ai.tweenable.VirtualIndestructibleAccessor;
import org.bronycorps.mlptss.manager.TrajectFactory;
import org.bronycorps.mlptss.manager.ai.playerimpl.DummyEnemyActor;
import org.bronycorps.mlptss.manager.preferences.TrajectConfiguration;

import aurelienribon.tweenengine.Timeline;
import aurelienribon.tweenengine.Tween;
import aurelienribon.tweenengine.TweenManager;

import com.badlogic.gdx.math.Vector2;

public class PredictionManager {

	private PredictedStage stage;

	private TweenManager tweenManager;

	public PredictionManager() {
		super();

		this.tweenManager = new TweenManager();
		this.stage = new PredictedStage();

		Tween.registerAccessor(VirtualDestructibleActor.class,
				new VirtualDestructibleAccessor());
		Tween.registerAccessor(VirtualIndestructibleActor.class,
				new VirtualIndestructibleAccessor());
	}

	public VirtualDestructibleActor addDummyEnemy(DummyEnemyActor actor,
			TrajectConfiguration traject) {
		VirtualDestructibleActor virtualActor = new VirtualDestructibleActor(
				actor);
		this.stage.getActors().add(virtualActor);
		Timeline timeline = TrajectFactory.getInstance().tweenVirtualEnemy(
				virtualActor, traject);
		TweenManager.setAutoRemove(timeline, false);
		timeline.start(this.tweenManager);
		return virtualActor;
	}

	public void addEnemy(EnemyActor actor, TrajectConfiguration traject) {
		VirtualDestructibleActor virtualActor = new VirtualDestructibleActor(
				actor);
		this.stage.getActors().add(virtualActor);
		Timeline timeline = TrajectFactory.getInstance().tweenVirtualEnemy(
				virtualActor, traject);
		TweenManager.setAutoRemove(timeline, false);
		timeline.start(this.tweenManager);
	}

	public void addMissile(MissileActor missile) {
		VirtualIndestructibleActor virtualActor = new VirtualIndestructibleActor(
				missile);
		this.stage.getActors().add(virtualActor);
		Timeline timeline = TrajectFactory.getInstance().tweenVirtualMissile(
				virtualActor, missile.getMissile().getModel().getTraject());
		TweenManager.setAutoRemove(timeline, false);
		timeline.start(this.tweenManager);
	}

	public void addSpecialMissile(VirtualActor virtualActor, Timeline timeline) {
		this.stage.getActors().add(virtualActor);
		TweenManager.setAutoRemove(timeline, false);
		timeline.start(this.tweenManager);
	}

	public void getPositionValue(Vector2 position) {

	}

	public PredictedStage getStage() {
		return this.stage;
	}

	public void removeActor(AbstractActor actor) {
		VirtualActor vactor = null;
		for (VirtualActor virtualActor : this.stage.getActors()) {
			if (virtualActor.getSource() == actor) {
				vactor = virtualActor;
				break;
			}
		}
		if (vactor != null) {
			// remove tween related to enemy
			this.tweenManager.killTarget(vactor);
			this.stage.getActors().remove(vactor);
		}
	}

	public void removeEnemy(EnemyActor actor) {
		VirtualActor enemy = null;
		for (VirtualActor virtualActor : this.stage.getActors()) {
			if (virtualActor.getSource() == actor) {
				enemy = virtualActor;
				break;
			}
		}
		if (enemy != null) {
			// remove tween related to enemy
			this.tweenManager.killTarget(enemy);
			this.stage.getActors().remove(enemy);
		}
	}

	public void removeMissile(MissileActor actor) {
		VirtualActor missile = null;
		for (VirtualActor virtualActor : this.stage.getActors()) {
			if (virtualActor.getSource() == actor) {
				missile = virtualActor;
				break;
			}
		}
		if (missile != null) {
			// remove tween related to enemy
			this.tweenManager.killTarget(missile);
			this.stage.getActors().remove(missile);
		}
	}

	public void removeSpecialMissile(SpecialMissileActor actor) {
		VirtualActor missile = null;
		for (VirtualActor virtualActor : this.stage.getActors()) {
			if (virtualActor.getSource() == actor) {
				missile = virtualActor;
				break;
			}
		}
		if (missile != null) {
			// remove tween related to enemy
			this.tweenManager.killTarget(missile);
			this.stage.getActors().remove(missile);
		}
	}

	public void update(float delta) {
		this.tweenManager.update(delta);
	}

}
